home *** CD-ROM | disk | FTP | other *** search
/ MacHack 2000 / MacHack 2000.toast / pc / The Hacks / MacHacksBug / Python 1.5.2c1 / Mac / Lib / ic.py < prev    next >
Encoding:
Python Source  |  2000-06-23  |  6.6 KB  |  265 lines

  1. """IC wrapper module, based on Internet Config 1.3"""
  2.  
  3. import icglue
  4. import string
  5. import sys
  6. import Res
  7. import macfs
  8. import macostools
  9.  
  10. error=icglue.error
  11.  
  12. # From ictypes.h:
  13. icPrefNotFoundErr = -666        # preference not found (duh!)
  14. icPermErr = -667                # cannot set preference
  15. icPrefDataErr = -668            # problem with preference data
  16. icInternalErr = -669            # hmm, this is not good
  17. icTruncatedErr = -670            # more data was present than was returned
  18. icNoMoreWritersErr = -671        # you cannot begin a write session because someone else is already doing it */
  19. icNothingToOverrideErr = -672    # no component for the override component to capture
  20. icNoURLErr = -673                # no URL found
  21. icConfigNotFoundErr = -674        # no configuration was found
  22. icConfigInappropriateErr = -675    # incorrect manufacturer code
  23.  
  24. ICattr_no_change = -1
  25.  
  26. icNoPerm = 0
  27. icReadOnlyPerm = 1
  28. icReadWritePerm = 2
  29. # End of ictypes.h
  30.  
  31. class ICOpaqueData:
  32.     """An unparseable IC entry"""
  33.     def __init__(self, data):
  34.         self.data = data
  35.  
  36.     def __repr__(self):
  37.         return "ICOpaqueData(%s)"%`self.data`
  38.  
  39. _ICOpaqueDataType=type(ICOpaqueData(''))
  40.         
  41. def _decode_default(data, key):
  42.     if len(data) == 0:
  43.         return data
  44.     if ord(data[0]) == len(data)-1:
  45.         # Assume Pstring
  46.         return data[1:]
  47.     return ICOpaqueData(data)
  48.     
  49.     
  50. def _decode_multistr(data, key):
  51.     numstr = ord(data[0]) << 8 | ord(data[1])
  52.     rv = []
  53.     ptr = 2
  54.     for i in range(numstr):
  55.         strlen = ord(data[ptr])
  56.         str = data[ptr+1:ptr+strlen+1]
  57.         rv.append(str)
  58.         ptr = ptr + strlen + 1
  59.     return rv
  60.     
  61. def _decode_fontrecord(data, key):
  62.     size = ord(data[0]) << 8 | ord(data[1])
  63.     face = ord(data[2])
  64.     namelen = ord(data[4])
  65.     return size, face, data[5:5+namelen]
  66.     
  67. def _decode_boolean(data, key):
  68.     return ord(data[0])
  69.     
  70. def _decode_text(data, key):
  71.     return data
  72.     
  73. def _decode_charset(data, key):
  74.     return data[:256], data[256:]
  75.     
  76. def _decode_appspec(data, key):
  77.     namelen = ord(data[4])
  78.     return data[0:4], data[5:5+namelen]
  79.  
  80. def _code_default(data, key):
  81.     return chr(len(data)) + data
  82.         
  83. def _code_multistr(data, key):
  84.     numstr = len(data)
  85.     rv = chr((numstr>>8) & 0xff) + chr(numstr & 0xff)
  86.     for i in data:
  87.         rv = rv + _code_default(i)
  88.     return rv
  89.     
  90. def _code_fontrecord(data, key):
  91.     size, face, name = data
  92.     return chr((size>>8) & 0xff) + chr(size & 0xff) + chr(face & 0xff) + \
  93.         chr(0) + _code_default(name)
  94.     
  95. def _code_boolean(data, key):
  96.     print 'XXXX boolean:', `data`
  97.     return chr(data)
  98.     
  99. def _code_text(data, key):
  100.     return data
  101.     
  102. def _code_charset(data, key):
  103.     return data[0] + data[1]
  104.     
  105. def _code_appspec(data, key):
  106.     return data[0] + _code_default(data[1])
  107.     
  108. _decoder_table = {
  109.     "ArchieAll" : (_decode_multistr , _code_multistr),
  110.     "UMichAll" : (_decode_multistr , _code_multistr),
  111.     "InfoMacAll" : (_decode_multistr , _code_multistr),
  112.     "ListFont" : (_decode_fontrecord , _code_fontrecord),
  113.     "ScreenFont" : (_decode_fontrecord , _code_fontrecord),
  114.     "PrinterFont" : (_decode_fontrecord , _code_fontrecord),
  115. #    "DownloadFolder" : (_decode_filespec , _code_filespec),
  116.     "Signature": (_decode_text , _code_text),
  117.     "Plan" : (_decode_text , _code_text),
  118.     "MailHeaders" : (_decode_text , _code_text),
  119.     "NewsHeaders" : (_decode_text , _code_text),
  120. #    "Mapping" 
  121.     "CharacterSet" : (_decode_charset , _code_charset),
  122.     "Helper\245" : (_decode_appspec , _code_appspec),
  123. #    "Services" : (_decode_services, ????),
  124.     "NewMailFlashIcon" : (_decode_boolean , _code_boolean),
  125.     "NewMailDialog" : (_decode_boolean , _code_boolean),
  126.     "NewMailPlaySound" : (_decode_boolean , _code_boolean),
  127. #    "WebBackgroundColor" : _decode_color,
  128.     "NoProxyDomains" : (_decode_multistr , _code_multistr),
  129.     "UseHTTPProxy" : (_decode_boolean , _code_boolean),
  130.     "UseGopherProxy": (_decode_boolean , _code_boolean),
  131.     "UseFTPProxy" : (_decode_boolean , _code_boolean),
  132.     "UsePassiveFTP" : (_decode_boolean , _code_boolean),
  133. }
  134.  
  135. def _decode(data, key):
  136.     if '\245' in key:
  137.         key2 = key[:string.index(key, '\245')+1]
  138.     else:
  139.         key2 = key
  140.     if _decoder_table.has_key(key2):
  141.         decoder = _decoder_table[key2][0]
  142.     else:
  143.         decoder = _decode_default
  144.     return decoder(data, key)
  145.  
  146. def _code(data, key):
  147.     if type(data) == _ICOpaqueDataType:
  148.         return data.data
  149.     if '\245' in key:
  150.         key2 = key[:string.index(key, '\245')+1]
  151.     else:
  152.         key2 = key
  153.     if _decoder_table.has_key(key2):
  154.         coder = _decoder_table[key2][1]
  155.     else:
  156.         coder = _code_default
  157.     return coder(data, key)
  158.     
  159. class IC:
  160.     def __init__(self, signature='Pyth', ic=None):
  161.         if ic:
  162.             self.ic = ic
  163.         else:
  164.             self.ic = icglue.ICStart(signature)
  165.             self.ic.ICFindConfigFile()
  166.         self.h = Res.Resource('')
  167.             
  168.     def keys(self):
  169.         rv = []
  170.         self.ic.ICBegin(icReadOnlyPerm)
  171.         num = self.ic.ICCountPref()
  172.         for i in range(num):
  173.             rv.append(self.ic.ICGetIndPref(i+1))
  174.         self.ic.ICEnd()
  175.         return rv
  176.         
  177.     def has_key(self, key):
  178.         try:
  179.             dummy = self.ic.ICFindPrefHandle(key, self.h)
  180.         except icglue.error:
  181.             return 0
  182.         return 1
  183.         
  184.     def __getitem__(self, key):
  185.         attr = self.ic.ICFindPrefHandle(key, self.h)
  186.         return _decode(self.h.data, key)
  187.         
  188.     def __setitem__(self, key, value):
  189.         value = _code(value, key)
  190.         self.ic.ICSetPref(key, ICattr_no_change, value)
  191.         
  192.     def launchurl(self, url, hint=""):
  193.         self.ic.ICLaunchURL(hint, url, 0, len(url))
  194.         
  195.     def parseurl(self, data, start=None, end=None, hint=""):
  196.         if start == None:
  197.             selStart = 0
  198.             selEnd = len(data)
  199.         else:
  200.             selStart = selEnd = start
  201.         if end != None:
  202.             selEnd = end
  203.         selStart, selEnd = self.ic.ICParseURL(hint, data, selStart, selEnd, self.h)
  204.         return self.h.data, selStart, selEnd
  205.         
  206.     def mapfile(self, file):
  207.         if type(file) != type(''):
  208.             file = file.as_tuple()[2]
  209.         return self.ic.ICMapFilename(file)
  210.         
  211.     def maptypecreator(self, type, creator, filename=""):
  212.         return self.ic.ICMapTypeCreator(type, creator, filename)
  213.         
  214.     def settypecreator(self, file):
  215.         if type(file) == type(''):
  216.             fss = macfs.FSSpec(file)
  217.         else:
  218.             fss = file
  219.         name = fss.as_tuple()[2]
  220.         record = self.mapfile(name)
  221.         fss.SetCreatorType(record[2], record[1])
  222.         macostools.touched(fss)
  223.         
  224. # Convenience routines
  225. _dft_ic = None
  226.  
  227. def launchurl(url, hint=""):
  228.     global _dft_ic
  229.     if _dft_ic == None: _dft_ic = IC()
  230.     return _dft_ic.launchurl(url, hint)
  231.     
  232. def parseurl(data, start=None, end=None, hint=""):
  233.     global _dft_ic
  234.     if _dft_ic == None: _dft_ic = IC()
  235.     return _dft_ic.parseurl(data, start, end, hint)
  236.     
  237. def mapfile(filename):
  238.     global _dft_ic
  239.     if _dft_ic == None: _dft_ic = IC()
  240.     return _dft_ic.mapfile(filename)
  241.     
  242. def maptypecreator(type, creator, filename=""):
  243.     global _dft_ic
  244.     if _dft_ic == None: _dft_ic = IC()
  245.     return _dft_ic.maptypecreator(type, creator, filename)
  246.     
  247. def settypecreator(file):
  248.     global _dft_ic
  249.     if _dft_ic == None: _dft_ic = IC()
  250.     return _dft_ic.settypecreator(file)
  251.         
  252. def _test():
  253.     ic = IC()
  254.     for k in ic.keys():
  255.         try:
  256.             v = ic[k]
  257.         except error:
  258.             v = '????'
  259.         print k, '\t', v
  260.     sys.exit(1)
  261.     
  262. if __name__ == '__main__':
  263.     _test()
  264.     
  265.